package com.huawei.esdk.tpoa.northcommu.cxf.professional.convert;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;

import com.huawei.esdk.platform.common.SDKResult;
import com.huawei.esdk.platform.common.utils.DateUtils;
import com.huawei.esdk.platform.common.utils.DurationUtils;
import com.huawei.esdk.platform.common.utils.StringUtils;
import com.huawei.esdk.tp.common.EnumRangeUtils;
import com.huawei.esdk.platform.common.config.ConfigManager;
import com.huawei.esdk.platform.common.exception.SDKException;
import com.huawei.esdk.tp.cxf.enumgen.DayOfWeekMapping;
import com.huawei.esdk.tp.cxf.enumgen.DialMode;
import com.huawei.esdk.tp.cxf.enumgen.DialModeMapping;
import com.huawei.esdk.tp.cxf.enumgen.MediaEncryptTypeMapping;
import com.huawei.esdk.tp.cxf.enumgen.PresentationTypeMapping;
import com.huawei.esdk.tp.cxf.enumgen.RecurrenceFrequency;
import com.huawei.esdk.tp.cxf.enumgen.RecurrenceFrequencyMapping;
import com.huawei.esdk.tp.cxf.enumgen.SiteFrom;
import com.huawei.esdk.tp.cxf.enumgen.SiteFromMapping;
import com.huawei.esdk.tp.cxf.enumgen.SiteType;
import com.huawei.esdk.tp.cxf.enumgen.SiteTypeMapping;
import com.huawei.esdk.tp.cxf.enumgen.VideoFormatMapping;
import com.huawei.esdk.tp.domain.model.PeriodicalConference;
import com.huawei.esdk.tp.domain.model.ScheduleConference;
import com.huawei.esdk.tp.domain.model.Site;
import com.huawei.esdk.tp.domain.model.SiteInConference;
import com.huawei.esdk.tpoa.business.oa.sitemgr.TPOASiteManager;
import com.huawei.esdk.tpoa.northcommu.cxf.professional.gen.ConferenceInfo;
import com.huawei.esdk.tpoa.northcommu.cxf.professional.gen.EditRecurrenceConference;
import com.huawei.esdk.tpoa.northcommu.cxf.professional.gen.EditRecurrenceConferenceResponse;
import com.huawei.esdk.tpoa.northcommu.cxf.professional.gen.EditScheduledConf;
import com.huawei.esdk.tpoa.northcommu.cxf.professional.gen.EditScheduledConfResponse;
import com.huawei.esdk.tpoa.northcommu.cxf.professional.gen.RecurrenceConfInfo;
import com.huawei.esdk.tpoa.northcommu.cxf.professional.gen.ScheduleConf;
import com.huawei.esdk.tpoa.northcommu.cxf.professional.gen.ScheduleConfResponse;
import com.huawei.esdk.tpoa.northcommu.cxf.professional.gen.ScheduleRecurrenceConference;
import com.huawei.esdk.tpoa.northcommu.cxf.professional.gen.ScheduleRecurrenceConferenceResponse;
import com.huawei.esdk.tpoa.northcommu.cxf.professional.gen.SiteAccessInfo;
import com.huawei.esdk.tpoa.northcommu.cxf.professional.gen.SiteInfo;

/** * @author w00208247 * * */
public class TPOAConfMgrConvert
{
    
    /**
     * 预约会议，预约周期会议，修改会议 ConferenceInfoEx赋值 预约会议，预约带匿名会场的会议，修改会议
     * 三个方法传入的参数除了类型不一致以外，里面的内容完全一致 将三个bean的赋值合并 北向soapbean转北向领域bean，用于赋值的情况
     */
    private void conferenceInfoExSoap2model(ConferenceInfo conferenceInfoEx, ScheduleConference conference)
        throws SDKException
    {
        // 通过领域模型将行业相关bean转到产品无关bean
        String confName = conferenceInfoEx.getName();
        
        if (null == confName || confName.isEmpty())
        {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            String currentDateStr = sdf.format(new Date());
            confName = ConfigManager.getInstance().getValue("tpoa_default_confName") + " " + currentDateStr;
        }
        
        XMLGregorianCalendar beginTime = conferenceInfoEx.getBeginTime();
        Duration duration = conferenceInfoEx.getDuration();
        String rate = conferenceInfoEx.getRate();
        // 预约会议，预约静态会议的时候confId是0
        String confId = conferenceInfoEx.getConfId();
        conference.setId(confId);
        List<SiteInConference> siteInConferences = new ArrayList<SiteInConference>();
        conference.setName(confName);
        conference.setBeginTime(DateUtils.toDate(DateUtils.setTimezoneToUTC(beginTime, 0)));
        // 将用户输入的duration类型转换成long，分钟为单位
        conference.setLength(DurationUtils.duration2int(duration));
        conference.setAccessCode(conferenceInfoEx.getAccessCode());

        conference.setPassword(conferenceInfoEx.getPassword());
        
        conference.setChairmanPassword(conferenceInfoEx.getChairmanPassword());
        
        // 判断枚举类型是否超出范围
        EnumRangeUtils.enumRange(conferenceInfoEx.getMediaEncryptType(), MediaEncryptTypeMapping.class);
        conference.setMediaEncryptType(conferenceInfoEx.getMediaEncryptType());
        
        // 判断枚举类型是否超出范围
        EnumRangeUtils.enumRange(conferenceInfoEx.getAuxVideoFormat(), VideoFormatMapping.class);
        
        conference.setAuxVideoFormat(conferenceInfoEx.getAuxVideoFormat());
        
        conference.setAuxVideoProtocol(conferenceInfoEx.getAuxVideoProtocol());
        
        conference.setCpResouce(conferenceInfoEx.getCpResouce());
        conference.setRate(rate);
        
        // boolean类型的边界值判断，只允许输入0,1
        EnumRangeUtils.enumRange(conferenceInfoEx.getIsRecording(), Boolean.class);
        conference.setIsRecording(conferenceInfoEx.getIsRecording());
        conference.setRecorderAddr(conferenceInfoEx.getRecorderAddr());
        
        // boolean类型的边界值判断，只允许输入0,1
        EnumRangeUtils.enumRange(conferenceInfoEx.getIsLiveBroadcast(), Boolean.class);
        conference.setIsLiveBroadcast(conferenceInfoEx.getIsLiveBroadcast());
        
        EnumRangeUtils.enumRange(conferenceInfoEx.getPresentation(), PresentationTypeMapping.class);
        conference.setPresentation(conferenceInfoEx.getPresentation());
        conference.setBillCode(conferenceInfoEx.getBillCode());
        SiteInConference site = null;
        List<SiteInfo> siteInfos = conferenceInfoEx.getSites();
        for (SiteInfo siteInfo : siteInfos)
        {
            // 北向soap bean转领域模型
            if (null != siteInfo)
            {
                site = siteInfoExSoap2model(siteInfo, null);
            }
            siteInConferences.add(site);
        }
        
        conference.setSites(siteInConferences);
    }
    
    /**
     * 会场信息转换 给SiteInfoEx赋值 北向soapbean转北向领域bean 会场信息转换 北向soapbean转北向领域bean
     */
    private SiteInConference siteInfoExSoap2model(SiteInfo siteInfo, SiteAccessInfo siteAccessInfoEx)
        throws SDKException
    {
        SiteInConference site = new SiteInConference();
        site.setUri(siteInfo.getUri());
        site.setName(siteInfo.getName());
        
        // 判断SiteType是否在用户可选的枚举范围之内
        if(null != siteInfo.getType() && -1 == siteInfo.getType())
        {
            site.setSiteType(null);
        }
        else
        {
            EnumRangeUtils.enumRange(siteInfo.getType(), SiteTypeMapping.class);
            SiteType siteType = SiteTypeMapping.int2Enum(siteInfo.getType());
            site.setSiteType(null == siteType ? null : siteType.toString());
        }
        
        // 判断SiteFormat是否在用户可选的枚举范围之内
        EnumRangeUtils.enumRange(siteInfo.getFrom(), SiteFromMapping.class);
        SiteFrom siteFrom = SiteFromMapping.int2Enum(siteInfo.getFrom());
        site.setFrom(null == siteFrom ? null : siteFrom.toString());
        
        // 判断DialMode是否在用户可选的枚举范围之内
        EnumRangeUtils.enumRange(siteInfo.getDialingMode(), DialModeMapping.class);
        DialMode dialMode = DialModeMapping.int2Enum(siteInfo.getDialingMode());
        site.setDialingMode(null == dialMode ? null : dialMode.toString());
        site.setRate(siteInfo.getRate());
        site.setVideoFormat(siteInfo.getVideoFormat());
        site.setVideoProtocol(siteInfo.getVideoProtocol());
        site.setStatus(siteInfo.getStatus());
        return site;
    }
    
    /**
     * 预约周期会议
     */
    
    /**
     * 预约会议，预约带匿名会场的会议，修改会议 三个方法传入的参数除了类型不一致以外，里面的内容完全一致 将三个bean的赋值合并
     * 北向soapbean转北向领域bean，用于赋值的情况
     */
    private PeriodicalConference scheduleRecurrenceConfCommSoap2model(ScheduleRecurrenceConference parameters)
        throws SDKException
    {
        // 通过领域模型将行业相关bean转到产品无关bean
        PeriodicalConference conference = new PeriodicalConference();
        // 周期会议中与普通会议通用的属性赋值
        ConferenceInfo conferenceInfoEx = parameters.getScheduleConf();
        conferenceInfoExSoap2model(conferenceInfoEx, conference);
        
        // 周期会议特有的属性赋值
        RecurrenceConfInfo recurrenceConfInfoEx = parameters.getScheduleConf();
        
        // 判断RecurrenceFrequency是否在用户可选的枚举范围之内
        EnumRangeUtils.enumRange(recurrenceConfInfoEx.getFrequency(), RecurrenceFrequencyMapping.class);
        RecurrenceFrequency recurrenceFrequency =
            RecurrenceFrequencyMapping.int2Enum(recurrenceConfInfoEx.getFrequency());
        conference.setFrequency(null == recurrenceFrequency ? null : recurrenceFrequency.toString());
        conference.setInterval(recurrenceConfInfoEx.getInterval());
        
        // recurrenceConfInfoEx.getWeekDays()中List的每个值的返回是0~6之间
        for (Integer week : recurrenceConfInfoEx.getWeekDays())
        {
            EnumRangeUtils.enumRange(week, DayOfWeekMapping.class);
        }
        conference.setWeekDays(recurrenceConfInfoEx.getWeekDays());
        conference.setWeekDay(recurrenceConfInfoEx.getWeekDay());
        conference.setMonthDay(recurrenceConfInfoEx.getMonthDay());
        conference.setCount(recurrenceConfInfoEx.getCount());
        conference.setEndDate(DateUtils.toDate(DateUtils.setTimezoneToUTC(recurrenceConfInfoEx.getEndDate(), 0)));
        //R3C10
        conference.setTimeZone(recurrenceConfInfoEx.getTimeZone());
        
        return conference;
    }
    
    /**
     * * 根据领域返回对北向soapbean值赋值
     * @param result /** * @param scheduleConfResponse /** * @return
     */
    private void setConferenceEx(long errorCode, ScheduleConference conference,
        ScheduleConfResponse scheduleConfResponse)
    {
        scheduleConfResponse.setResultCode((int)errorCode);
        // 从返回值中取出返回消息，赋给北向soapbean
        // 首先判断返回值是否为0，如果不为0，直接返回错误码
        if (errorCode != 0)
        {
            return;
        }
        ConferenceInfo conferenceInfo = new ConferenceInfo();
        conferenceInfo.setConfId(conference.getId() + "");
        conferenceInfo.setRecorderAddr(conference.getRecorderAddr());
        
        List<SiteInConference> siteInConferences = conference.getSites();
        SiteInfo siteInfo = null;
        for (SiteInConference siteInConference : siteInConferences)
        {
            siteInfo = new SiteInfo();
            
            siteInfo.setUri(siteInConference.getUri());
            siteInfo.setName(siteInConference.getName());
            
            // 返回多个accessCode，考虑多MCU的情况
            conferenceInfo.setAccessCode(siteInConference.getAccessCode());
            conferenceInfo.getSites().add(siteInfo);
        }
        
        scheduleConfResponse.setConferenceInfo(conferenceInfo);
    }
    
    private void setRecurrenceConfInfo(long errorCode, ScheduleConference conference,
        ScheduleRecurrenceConferenceResponse scheduleConfResponse)
    {
        scheduleConfResponse.setResultCode((int)errorCode);
        // 从返回值中取出返回消息，赋给北向soapbean
        // 首先判断返回值是否为0，如果不为0，直接返回错误码
        if (errorCode != 0)
        {
            return;
        }
        RecurrenceConfInfo conferenceInfo = new RecurrenceConfInfo();
        conferenceInfo.setConfId(conference.getId() + "");
        conferenceInfo.setRecorderAddr(conference.getRecorderAddr());
        
        List<SiteInConference> siteInConferences = conference.getSites();
        SiteInfo siteInfo = null;
        SiteAccessInfo siteAccessInfoEx = null;
        for (SiteInConference siteInConference : siteInConferences)
        {
            siteInfo = new SiteInfo();
            siteAccessInfoEx = new SiteAccessInfo();
            
            siteInfo.setUri(siteInConference.getUri());
            siteInfo.setName(siteInConference.getName());
            // 返回多个accessCode，考虑多MCU的情况
            siteAccessInfoEx.setUri(siteInConference.getUri());
            siteAccessInfoEx.setConfAccessCode(siteInConference.getAccessCode());
            
            siteAccessInfoEx.setBeginTime(DateUtils.setTimezoneToUTC(
                DateUtils.toGregorianCalendarDateSMC(siteInConference.getBeginTime()),
                null));
            siteAccessInfoEx.setMcuUri(siteInConference.getMcuUri());
            conferenceInfo.getSites().add(siteInfo);
            conferenceInfo.getSiteAccessInfos().add(siteAccessInfoEx);
        }
        
        scheduleConfResponse.setRecurrenceConfInfo(conferenceInfo);
    }
    
    /**
     * 预约会议，修改会议共用 北向领域bean转北向soap bean，用于返回的情况
     */
    private ScheduleConfResponse scheduleConfCommModel2soap(SDKResult<ScheduleConference> result)
    {
        ScheduleConfResponse scheduleConfResponse = new ScheduleConfResponse();
        setConferenceEx(result.getErrCode(), result.getResult(), scheduleConfResponse);
        return scheduleConfResponse;
    }
    
    /**
     * 预约周期会议，model2soap 预约会议，修改会议共用 北向领域bean转北向soap bean，用于返回的情况
     */
    private ScheduleRecurrenceConferenceResponse scheduleRecurrenceConfCommModel2soap(
        SDKResult<PeriodicalConference> result)
    {
        ScheduleRecurrenceConferenceResponse scheduleRecurrenceConferenceExResponse =
            new ScheduleRecurrenceConferenceResponse();
        setRecurrenceConfInfo(result.getErrCode(), result.getResult(), scheduleRecurrenceConferenceExResponse);
        scheduleRecurrenceConferenceExResponse.setRecurrenceConfInfo(scheduleRecurrenceConferenceExResponse.getRecurrenceConfInfo());
        return scheduleRecurrenceConferenceExResponse;
    }
    
    /**
     * 预约会议，北向soapbean转北向领域bean 用于赋值的情况 ModelBean soap2model(SoapBean){}
     * 预约会议，北向soapbean转北向领域bean 用于赋值的情况 ModelBean soap2model(SoapBean){}
     */
    public ScheduleConference scheduleConfSoap2model(ScheduleConf parameters)
        throws Exception
    {
        ScheduleConference scheduleConference = new ScheduleConference();
        conferenceInfoExSoap2model(parameters.getScheduleConf(), scheduleConference);
        return scheduleConference;
    }
    
    /**
     * 预约会议，北向领域bean转北向soap bean 用于返回的情况 response model2soap
     */
    public ScheduleConfResponse scheduleConferenceModel2soap(SDKResult<ScheduleConference> result)
    {
        return scheduleConfCommModel2soap(result);
    }
    
    /**
     * 预约周期会议， 北向soapbean转北向领域bean 用于赋值的情况 ModelBean soap2model(SoapBean){}
     */
    public PeriodicalConference scheduleRecurrenceConfSoap2model(ScheduleRecurrenceConference parameters)
        throws Exception
    {
        return scheduleRecurrenceConfCommSoap2model(parameters);
    }
    
    /**
     * 预约周期会议，北向领域bean转北向soap bean 用于返回的情况 response model2soap
     */
    public ScheduleRecurrenceConferenceResponse scheduleRecurrenceConfModel2soap(SDKResult<PeriodicalConference> result)
    {
        
        return scheduleRecurrenceConfCommModel2soap(result);
    }
    
    /**
     * 修改会议，北向soapbean转北向领域bean 用于赋值的情况 ModelBean soap2model(SoapBean){}
     * 修改会议，北向soapbean转北向领域bean 用于赋值的情况 ModelBean soap2model(SoapBean){}
     */
    public ScheduleConference editScheduledConfSoap2model(EditScheduledConf parameters)
        throws Exception
    {
        ScheduleConference scheduleConference = new ScheduleConference();
        conferenceInfoExSoap2model(parameters.getEditConf(), scheduleConference);
        return scheduleConference;
    }
    
    /**
     * 预约带匿名会场的会议，北向领域bean转北向soap bean 用于返回的情况 response model2soap
     */
    public EditScheduledConfResponse editScheduledConfModel2soap(SDKResult<ScheduleConference> result)
    {
        EditScheduledConfResponse editScheduleConfResponse = new EditScheduledConfResponse();
        ScheduleConfResponse scheduleConfResponse = scheduleConfCommModel2soap(result);
        
        editScheduleConfResponse.setConferenceInfo(scheduleConfResponse.getConferenceInfo());
        editScheduleConfResponse.setResultCode(scheduleConfResponse.getResultCode());
        return editScheduleConfResponse;
    }
    
    /**
     * 修改周期会议，北向soapbean转北向领域bean 用于赋值的情况 ModelBean soap2model(SoapBean){}
     * 修改会议，北向soapbean转北向领域bean 用于赋值的情况 ModelBean soap2model(SoapBean){}
     */
    public PeriodicalConference editScheduledRecurrenceConfSoap2model(EditRecurrenceConference parameters)
        throws Exception
    {
        ScheduleRecurrenceConference scheduleRecurrenceConferenceEx = new ScheduleRecurrenceConference();
        scheduleRecurrenceConferenceEx.setScheduleConf(parameters.getEditConf());
        
        return scheduleRecurrenceConfCommSoap2model(scheduleRecurrenceConferenceEx);
    }
    
    /**
     * 修改周期会议，北向领域bean转北向soap bean 用于返回的情况 response model2soap
     */
    public EditRecurrenceConferenceResponse editScheduledRecurrenceConfModel2soap(SDKResult<PeriodicalConference> result)
    {
        EditRecurrenceConferenceResponse editScheduleConfResponse = new EditRecurrenceConferenceResponse();
        ScheduleRecurrenceConferenceResponse scheduleConfResponse = scheduleRecurrenceConfCommModel2soap(result);
        
        editScheduleConfResponse.setRecurrenceConfInfo(scheduleConfResponse.getRecurrenceConfInfo());
        editScheduleConfResponse.setResultCode(scheduleConfResponse.getResultCode());
        return editScheduleConfResponse;
    }
    
    public List<SiteInConference> convertSitesFrom365(List<SiteInConference> sites)
    {
        List<SiteInConference> result = new ArrayList<SiteInConference>();
        
        for (SiteInConference siteInConference : sites)
        {
            String siteUri = siteInConference.getUri();
            if (!StringUtils.isEmpty(siteUri))
            {   
                if(StringUtils.isEmpty(siteInConference.getSiteType()))
                {
                    int beginIndex = siteUri.indexOf("@");
                    if(-1 != beginIndex)
                    {
                        String tpSiteUri = siteUri.substring(0, beginIndex);
                        Site tpSite = TPOASiteManager.tpSites.get(tpSiteUri);
                        if(null != tpSite)
                        {
                            SiteInConference siteInConf = new SiteInConference();
                            siteInConf.setUri(tpSite.getUri());
                            siteInConf.setName(tpSite.getName());
                            siteInConf.setSiteType(tpSite.getSiteType());
                            result.add(siteInConf);
                        }
                    }
                }
                else
                {
                    result.add(siteInConference);
                }
            }
            else if (!StringUtils.isEmpty(siteInConference.getSiteType()))
            {
                result.add(siteInConference);
            }
        }

        return result;
    }
}
